package com.ruoyi.framework.websocket;

import java.util.concurrent.Semaphore;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.service.TokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * websocket 消息处理
 *
 * @author ruoyi
 */
@Component
@ServerEndpoint("/websocket/{uid}")
public class WebSocketServer {

    /**
     * WebSocketServer 日志控制器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * 默认最多允许同时在线人数100
     */
    public static int socketMaxOnlineCount = 100;

    private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);

    /**
     * 建立连接
     */
    @OnOpen
    public void onOpen(@PathParam("uid") String token, Session session) throws Exception {
        TokenService tokenService = SpringUtils.getBean("tokenService");
        LoginUser loginUserByToken = tokenService.getLoginUserByToken(token);
        if (loginUserByToken == null) {
            session.close();
            return;
        }
        boolean semaphoreFlag = false;
        // 尝试获取信号量
        semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
        if (!semaphoreFlag) {
            // 未获取到信号量
            LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
            session.close();
        } else {
            // 添加用户
            Long userId = loginUserByToken.getUserId();
            WebSocketJoinDomain webSocketJoinDomain = new WebSocketJoinDomain(userId.toString(),session);
            WebSocketUsers.put(token, webSocketJoinDomain);
            LOGGER.info("\n 建立连接 - {}", session);
            LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size());
        }
    }

    /**
     * 断开连接
     */
    @OnClose
    public void onClose(@PathParam("uid") String token, Session session) {
        // 移除用户
        boolean removeFlag = WebSocketUsers.remove(token);
        if (!removeFlag) {
            // 获取到信号量则需释放
            SemaphoreUtils.release(socketSemaphore);
        }
    }

    /**
     * 服务器接收到客户端消息时调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("接受消息：" + message);
        WebSocketUsers.sendMessageToUserByText(session, "返回消息：服务器接受到了");
    }
}